<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Histogram Calculation</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d9/df8/tutorial_root.html">OpenCV Tutorials</a></li><li class="navelem"><a class="el" href="../../d7/da8/tutorial_table_of_content_imgproc.html">Image Processing (imgproc module)</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Histogram Calculation </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><b>Prev Tutorial:</b> <a class="el" href="../../d4/d1b/tutorial_histogram_equalization.html">Histogram Equalization</a></p>
<p><b>Next Tutorial:</b> <a class="el" href="../../d8/dc8/tutorial_histogram_comparison.html">Histogram Comparison</a></p>
<table class="doxtable">
<tr>
<th align="right"></th><th align="left"></th></tr>
<tr>
<td align="right">Original author </td><td align="left">Ana Huamán </td></tr>
<tr>
<td align="right">Compatibility </td><td align="left">OpenCV &gt;= 3.0 </td></tr>
</table>
<h2>Goal </h2>
<p>In this tutorial you will learn how to:</p>
<ul>
<li>Use the OpenCV function <a class="el" href="../../d2/de8/group__core__array.html#ga0547c7fed86152d7e9d0096029c8518a">cv::split</a> to divide an image into its correspondent planes.</li>
<li>To calculate histograms of arrays of images by using the OpenCV function <a class="el" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">cv::calcHist</a></li>
<li>To normalize an array by using the function <a class="el" href="../../dc/d84/group__core__basic.html#ga1b6a396a456c8b6c6e4afd8591560d80">cv::normalize</a></li>
</ul>
<dl class="section note"><dt>Note</dt><dd>In the last tutorial (<a class="el" href="../../d4/d1b/tutorial_histogram_equalization.html">Histogram Equalization</a>) we talked about a particular kind of histogram called <em>Image histogram</em>. Now we will considerate it in its more general concept. Read on!</dd></dl>
<h3>What are histograms?</h3>
<ul>
<li>Histograms are collected <em>counts</em> of data organized into a set of predefined <em>bins</em></li>
<li>When we say <em>data</em> we are not restricting it to be intensity values (as we saw in the previous Tutorial <a class="el" href="../../d4/d1b/tutorial_histogram_equalization.html">Histogram Equalization</a>). The data collected can be whatever feature you find useful to describe your image.</li>
<li><p class="startli">Let's see an example. Imagine that a Matrix contains information of an image (i.e. intensity in the range \(0-255\)):</p>
<div class="image">
<img src="../../Histogram_Calculation_Theory_Hist0.jpg" alt="Histogram_Calculation_Theory_Hist0.jpg"/>
</div>
</li>
<li><p class="startli">What happens if we want to <em>count</em> this data in an organized way? Since we know that the <em>range</em> of information value for this case is 256 values, we can segment our range in subparts (called <b>bins</b>) like:</p>
<p class="formulaDsp">
\[\begin{array}{l} [0, 255] = { [0, 15] \cup [16, 31] \cup ....\cup [240,255] } \\ range = { bin_{1} \cup bin_{2} \cup ....\cup bin_{n = 15} } \end{array}\]
</p>
<p class="startli">and we can keep count of the number of pixels that fall in the range of each \(bin_{i}\). Applying this to the example above we get the image below ( axis x represents the bins and axis y the number of pixels in each of them).</p>
<div class="image">
<img src="../../Histogram_Calculation_Theory_Hist1.jpg" alt="Histogram_Calculation_Theory_Hist1.jpg"/>
</div>
</li>
<li>This was just a simple example of how an histogram works and why it is useful. An histogram can keep count not only of color intensities, but of whatever image features that we want to measure (i.e. gradients, directions, etc).</li>
<li>Let's identify some parts of the histogram:<ol type="1">
<li><b>dims</b>: The number of parameters you want to collect data of. In our example, <b>dims = 1</b> because we are only counting the intensity values of each pixel (in a greyscale image).</li>
<li><b>bins</b>: It is the number of <b>subdivisions</b> in each dim. In our example, <b>bins = 16</b></li>
<li><b>range</b>: The limits for the values to be measured. In this case: <b>range = [0,255]</b></li>
</ol>
</li>
<li>What if you want to count two features? In this case your resulting histogram would be a 3D plot (in which x and y would be \(bin_{x}\) and \(bin_{y}\) for each feature and z would be the number of counts for each combination of \((bin_{x}, bin_{y})\). The same would apply for more features (of course it gets trickier).</li>
</ul>
<h3>What OpenCV offers you</h3>
<p>For simple purposes, OpenCV implements the function <a class="el" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">cv::calcHist</a> , which calculates the histogram of a set of arrays (usually images or image planes). It can operate with up to 32 dimensions. We will see it in the code below!</p>
<h2>Code </h2>
<ul>
<li><b>What does this program do?</b><ul>
<li>Loads an image</li>
<li>Splits the image into its R, G and B planes using the function <a class="el" href="../../d2/de8/group__core__array.html#ga0547c7fed86152d7e9d0096029c8518a">cv::split</a></li>
<li>Calculate the Histogram of each 1-channel plane by calling the function <a class="el" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">cv::calcHist</a></li>
<li>Plot the three histograms in a window</li>
</ul>
</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="../../d4/dd5/highgui_8hpp.html">opencv2/highgui.hpp</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="../../d6/d87/imgcodecs_8hpp.html">opencv2/imgcodecs.hpp</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="../../d1/d4f/imgproc_2include_2opencv2_2imgproc_8hpp.html">opencv2/imgproc.hpp</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span>std;</div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../d2/d75/namespacecv.html">cv</a>;</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>** argv)</div><div class="line">{</div><div class="line">    <a class="code" href="../../d0/d2e/classcv_1_1CommandLineParser.html">CommandLineParser</a> parser( argc, argv, <span class="stringliteral">&quot;{@input | lena.jpg | input image}&quot;</span> );</div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> src = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;( <span class="stringliteral">&quot;@input&quot;</span> ) ), <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80af660544735200cbe942eea09232eb822">IMREAD_COLOR</a> );</div><div class="line">    <span class="keywordflow">if</span>( src.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#abbec3525a852e77998aba034813fded4">empty</a>() )</div><div class="line">    {</div><div class="line">        <span class="keywordflow">return</span> EXIT_FAILURE;</div><div class="line">    }</div><div class="line"></div><div class="line">    vector&lt;Mat&gt; bgr_planes;</div><div class="line">    <a class="code" href="../../d2/de8/group__core__array.html#ga0547c7fed86152d7e9d0096029c8518a">split</a>( src, bgr_planes );</div><div class="line"></div><div class="line">    <span class="keywordtype">int</span> histSize = 256;</div><div class="line"></div><div class="line">    <span class="keywordtype">float</span> range[] = { 0, 256 }; <span class="comment">//the upper boundary is exclusive</span></div><div class="line">    <span class="keyword">const</span> <span class="keywordtype">float</span>* <a class="code" href="../../d8/d0e/group__cudaimgproc__hist.html#ga87819085c1059186d9cdeacd92cea783">histRange</a> = { range };</div><div class="line"></div><div class="line">    <span class="keywordtype">bool</span> uniform = <span class="keyword">true</span>, <a class="code" href="../../d7/df3/group__imgproc__motion.html#ga1a567a79901513811ff3b9976923b199">accumulate</a> = <span class="keyword">false</span>;</div><div class="line"></div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> b_hist, g_hist, r_hist;</div><div class="line">    <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">calcHist</a>( &amp;bgr_planes[0], 1, 0, <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a>(), b_hist, 1, &amp;histSize, &amp;histRange, uniform, <a class="code" href="../../d7/df3/group__imgproc__motion.html#ga1a567a79901513811ff3b9976923b199">accumulate</a> );</div><div class="line">    <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">calcHist</a>( &amp;bgr_planes[1], 1, 0, <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a>(), g_hist, 1, &amp;histSize, &amp;histRange, uniform, <a class="code" href="../../d7/df3/group__imgproc__motion.html#ga1a567a79901513811ff3b9976923b199">accumulate</a> );</div><div class="line">    <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">calcHist</a>( &amp;bgr_planes[2], 1, 0, <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a>(), r_hist, 1, &amp;histSize, &amp;histRange, uniform, <a class="code" href="../../d7/df3/group__imgproc__motion.html#ga1a567a79901513811ff3b9976923b199">accumulate</a> );</div><div class="line"></div><div class="line">    <span class="keywordtype">int</span> hist_w = 512, hist_h = 400;</div><div class="line">    <span class="keywordtype">int</span> bin_w = <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>( (<span class="keywordtype">double</span>) hist_w/histSize );</div><div class="line"></div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> histImage( hist_h, hist_w, <a class="code" href="../../d1/d1b/group__core__hal__interface.html#ga88c4cd9de76f678f33928ef1e3f96047">CV_8UC3</a>, <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>( 0,0,0) );</div><div class="line"></div><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga1b6a396a456c8b6c6e4afd8591560d80">normalize</a>(b_hist, b_hist, 0, histImage.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#abed816466c45234254d25bc59c31245e">rows</a>, <a class="code" href="../../d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa9f0c1c342a18114d47b516a88e29822e">NORM_MINMAX</a>, -1, <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a>() );</div><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga1b6a396a456c8b6c6e4afd8591560d80">normalize</a>(g_hist, g_hist, 0, histImage.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#abed816466c45234254d25bc59c31245e">rows</a>, <a class="code" href="../../d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa9f0c1c342a18114d47b516a88e29822e">NORM_MINMAX</a>, -1, <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a>() );</div><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga1b6a396a456c8b6c6e4afd8591560d80">normalize</a>(r_hist, r_hist, 0, histImage.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#abed816466c45234254d25bc59c31245e">rows</a>, <a class="code" href="../../d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa9f0c1c342a18114d47b516a88e29822e">NORM_MINMAX</a>, -1, <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a>() );</div><div class="line"></div><div class="line">    <span class="keywordflow">for</span>( <span class="keywordtype">int</span> i = 1; i &lt; histSize; i++ )</div><div class="line">    {</div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">line</a>( histImage, <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i-1), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(b_hist.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">float</span>&gt;(i-1)) ),</div><div class="line">              <a class="code" href="../../db/d4e/classcv_1_1Point__.html">Point</a>( bin_w*(i), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(b_hist.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">float</span>&gt;(i)) ),</div><div class="line">              <a class="code" href="../../d1/da0/classcv_1_1Scalar__.html">Scalar</a>( 255, 0, 0), 2, 8, 0  );</div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">line</a>( histImage, <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i-1), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(g_hist.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">float</span>&gt;(i-1)) ),</div><div class="line">              <a class="code" href="../../db/d4e/classcv_1_1Point__.html">Point</a>( bin_w*(i), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(g_hist.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">float</span>&gt;(i)) ),</div><div class="line">              <a class="code" href="../../d1/da0/classcv_1_1Scalar__.html">Scalar</a>( 0, 255, 0), 2, 8, 0  );</div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">line</a>( histImage, <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i-1), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(r_hist.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">float</span>&gt;(i-1)) ),</div><div class="line">              <a class="code" href="../../db/d4e/classcv_1_1Point__.html">Point</a>( bin_w*(i), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(r_hist.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">float</span>&gt;(i)) ),</div><div class="line">              <a class="code" href="../../d1/da0/classcv_1_1Scalar__.html">Scalar</a>( 0, 0, 255), 2, 8, 0  );</div><div class="line">    }</div><div class="line"></div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;Source image&quot;</span>, src );</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;calcHist Demo&quot;</span>, histImage );</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">waitKey</a>();</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> EXIT_SUCCESS;</div><div class="line">}</div></div><!-- fragment -->  </div> </li>
</ul>
 <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/Histograms_Matching/histogram_calculation/CalcHistDemo.java">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"><span class="keyword">import</span> java.util.ArrayList;</div><div class="line"><span class="keyword">import</span> java.util.List;</div><div class="line"></div><div class="line"><span class="keyword">import</span> org.opencv.core.Core;</div><div class="line"><span class="keyword">import</span> org.opencv.core.CvType;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Mat;</div><div class="line"><span class="keyword">import</span> org.opencv.core.MatOfFloat;</div><div class="line"><span class="keyword">import</span> org.opencv.core.MatOfInt;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Point;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Scalar;</div><div class="line"><span class="keyword">import</span> org.opencv.highgui.HighGui;</div><div class="line"><span class="keyword">import</span> org.opencv.imgcodecs.Imgcodecs;</div><div class="line"><span class="keyword">import</span> org.opencv.imgproc.Imgproc;</div><div class="line"></div><div class="line"><span class="keyword">class </span>CalcHist {</div><div class="line">    <span class="keyword">public</span> <span class="keywordtype">void</span> run(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] args) {</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename = args.length &gt; 0 ? args[0] : <span class="stringliteral">&quot;../data/lena.jpg&quot;</span>;</div><div class="line">        Mat src = Imgcodecs.imread(filename);</div><div class="line">        <span class="keywordflow">if</span> (src.empty()) {</div><div class="line">            System.err.println(<span class="stringliteral">&quot;Cannot read image: &quot;</span> + filename);</div><div class="line">            System.exit(0);</div><div class="line">        }</div><div class="line"></div><div class="line">        List&lt;Mat&gt; bgrPlanes = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        Core.split(src, bgrPlanes);</div><div class="line"></div><div class="line">        <span class="keywordtype">int</span> histSize = 256;</div><div class="line"></div><div class="line">        <span class="keywordtype">float</span>[] range = {0, 256}; <span class="comment">//the upper boundary is exclusive</span></div><div class="line">        MatOfFloat histRange = <span class="keyword">new</span> MatOfFloat(range);</div><div class="line"></div><div class="line">        <span class="keywordtype">boolean</span> <a class="code" href="../../d7/df3/group__imgproc__motion.html#ga1a567a79901513811ff3b9976923b199">accumulate</a> = <span class="keyword">false</span>;</div><div class="line"></div><div class="line">        Mat bHist = <span class="keyword">new</span> Mat(), gHist = <span class="keyword">new</span> Mat(), rHist = <span class="keyword">new</span> Mat();</div><div class="line">        Imgproc.calcHist(bgrPlanes, <span class="keyword">new</span> MatOfInt(0), <span class="keyword">new</span> Mat(), bHist, <span class="keyword">new</span> MatOfInt(histSize), histRange, accumulate);</div><div class="line">        Imgproc.calcHist(bgrPlanes, <span class="keyword">new</span> MatOfInt(1), <span class="keyword">new</span> Mat(), gHist, <span class="keyword">new</span> MatOfInt(histSize), histRange, accumulate);</div><div class="line">        Imgproc.calcHist(bgrPlanes, <span class="keyword">new</span> MatOfInt(2), <span class="keyword">new</span> Mat(), rHist, <span class="keyword">new</span> MatOfInt(histSize), histRange, accumulate);</div><div class="line"></div><div class="line">        <span class="keywordtype">int</span> histW = 512, histH = 400;</div><div class="line">        <span class="keywordtype">int</span> binW = (int) Math.round((<span class="keywordtype">double</span>) histW / histSize);</div><div class="line"></div><div class="line">        Mat histImage = <span class="keyword">new</span> Mat( histH, histW, CvType.CV_8UC3, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>( 0,0,0) );</div><div class="line"></div><div class="line">        Core.normalize(bHist, bHist, 0, histImage.rows(), Core.NORM_MINMAX);</div><div class="line">        Core.normalize(gHist, gHist, 0, histImage.rows(), Core.NORM_MINMAX);</div><div class="line">        Core.normalize(rHist, rHist, 0, histImage.rows(), Core.NORM_MINMAX);</div><div class="line"></div><div class="line">        <span class="keywordtype">float</span>[] bHistData = <span class="keyword">new</span> <span class="keywordtype">float</span>[(int) (bHist.total() * bHist.channels())];</div><div class="line">        bHist.get(0, 0, bHistData);</div><div class="line">        <span class="keywordtype">float</span>[] gHistData = <span class="keyword">new</span> <span class="keywordtype">float</span>[(int) (gHist.total() * gHist.channels())];</div><div class="line">        gHist.get(0, 0, gHistData);</div><div class="line">        <span class="keywordtype">float</span>[] rHistData = <span class="keyword">new</span> <span class="keywordtype">float</span>[(int) (rHist.total() * rHist.channels())];</div><div class="line">        rHist.get(0, 0, rHistData);</div><div class="line"></div><div class="line">        <span class="keywordflow">for</span>( <span class="keywordtype">int</span> i = 1; i &lt; histSize; i++ ) {</div><div class="line">            Imgproc.line(histImage, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i - 1), histH - Math.round(bHistData[i - 1])),</div><div class="line">                    <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i), histH - Math.round(bHistData[i])), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(255, 0, 0), 2);</div><div class="line">            Imgproc.line(histImage, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i - 1), histH - Math.round(gHistData[i - 1])),</div><div class="line">                    <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i), histH - Math.round(gHistData[i])), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(0, 255, 0), 2);</div><div class="line">            Imgproc.line(histImage, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i - 1), histH - Math.round(rHistData[i - 1])),</div><div class="line">                    <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i), histH - Math.round(rHistData[i])), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(0, 0, 255), 2);</div><div class="line">        }</div><div class="line"></div><div class="line">        HighGui.imshow( <span class="stringliteral">&quot;Source image&quot;</span>, src );</div><div class="line">        HighGui.imshow( <span class="stringliteral">&quot;calcHist Demo&quot;</span>, histImage );</div><div class="line">        HighGui.waitKey(0);</div><div class="line"></div><div class="line">        System.exit(0);</div><div class="line">    }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="keyword">class </span>CalcHistDemo {</div><div class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keywordtype">void</span> main(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] args) {</div><div class="line">        <span class="comment">// Load the native OpenCV library</span></div><div class="line">        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);</div><div class="line"></div><div class="line">        <span class="keyword">new</span> CalcHist().run(args);</div><div class="line">    }</div><div class="line">}</div></div><!-- fragment -->  </div> </li>
</ul>
 <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/Histograms_Matching/histogram_calculation/calcHist_Demo.py">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"><span class="keyword">from</span> __future__ <span class="keyword">import</span> print_function</div><div class="line"><span class="keyword">from</span> __future__ <span class="keyword">import</span> division</div><div class="line"><span class="keyword">import</span> cv2 <span class="keyword">as</span> cv</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> argparse</div><div class="line"></div><div class="line"></div><div class="line">parser = argparse.ArgumentParser(description=<span class="stringliteral">&#39;Code for Histogram Calculation tutorial.&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--input&#39;</span>, help=<span class="stringliteral">&#39;Path to input image.&#39;</span>, default=<span class="stringliteral">&#39;lena.jpg&#39;</span>)</div><div class="line">args = parser.parse_args()</div><div class="line"></div><div class="line">src = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">cv.imread</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(args.input))</div><div class="line"><span class="keywordflow">if</span> src <span class="keywordflow">is</span> <span class="keywordtype">None</span>:</div><div class="line">    <a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;Could not open or find the image:&#39;</span>, args.input)</div><div class="line">    exit(0)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">bgr_planes = <a class="code" href="../../d2/de8/group__core__array.html#ga8027f9deee1e42716be8039e5863fbd9">cv.split</a>(src)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">histSize = 256</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">histRange = (0, 256) <span class="comment"># the upper boundary is exclusive</span></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">accumulate = <span class="keyword">False</span></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">b_hist = <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga6ca1876785483836f72a77ced8ea759a">cv.calcHist</a>(bgr_planes, [0], <span class="keywordtype">None</span>, [histSize], histRange, accumulate=accumulate)</div><div class="line">g_hist = <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga6ca1876785483836f72a77ced8ea759a">cv.calcHist</a>(bgr_planes, [1], <span class="keywordtype">None</span>, [histSize], histRange, accumulate=accumulate)</div><div class="line">r_hist = <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga6ca1876785483836f72a77ced8ea759a">cv.calcHist</a>(bgr_planes, [2], <span class="keywordtype">None</span>, [histSize], histRange, accumulate=accumulate)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">hist_w = 512</div><div class="line">hist_h = 400</div><div class="line">bin_w = int(round( hist_w/histSize ))</div><div class="line"></div><div class="line">histImage = np.zeros((hist_h, hist_w, 3), dtype=np.uint8)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><a class="code" href="../../d2/de8/group__core__array.html#ga7bcf47a1df78cf575162e0aed44960cb">cv.normalize</a>(b_hist, b_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)</div><div class="line"><a class="code" href="../../d2/de8/group__core__array.html#ga7bcf47a1df78cf575162e0aed44960cb">cv.normalize</a>(g_hist, g_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)</div><div class="line"><a class="code" href="../../d2/de8/group__core__array.html#ga7bcf47a1df78cf575162e0aed44960cb">cv.normalize</a>(r_hist, r_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordflow">for</span> i <span class="keywordflow">in</span> range(1, histSize):</div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">cv.line</a>(histImage, ( bin_w*(i-1), hist_h - int(b_hist[i-1]) ),</div><div class="line">            ( bin_w*(i), hist_h - int(b_hist[i]) ),</div><div class="line">            ( 255, 0, 0), thickness=2)</div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">cv.line</a>(histImage, ( bin_w*(i-1), hist_h - int(g_hist[i-1]) ),</div><div class="line">            ( bin_w*(i), hist_h - int(g_hist[i]) ),</div><div class="line">            ( 0, 255, 0), thickness=2)</div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">cv.line</a>(histImage, ( bin_w*(i-1), hist_h - int(r_hist[i-1]) ),</div><div class="line">            ( bin_w*(i), hist_h - int(r_hist[i]) ),</div><div class="line">            ( 0, 0, 255), thickness=2)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;Source image&#39;</span>, src)</div><div class="line"><a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;calcHist Demo&#39;</span>, histImage)</div><div class="line"><a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">cv.waitKey</a>()</div><div class="line"></div></div><!-- fragment -->  </div> </li>
</ul>
<h2>Explanation </h2>
<ul>
<li>Load the source image</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    CommandLineParser parser( argc, argv, <span class="stringliteral">&quot;{@input | lena.jpg | input image}&quot;</span> );</div><div class="line">    Mat src = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;( <span class="stringliteral">&quot;@input&quot;</span> ) ), <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80af660544735200cbe942eea09232eb822">IMREAD_COLOR</a> );</div><div class="line">    <span class="keywordflow">if</span>( src.empty() )</div><div class="line">    {</div><div class="line">        <span class="keywordflow">return</span> EXIT_FAILURE;</div><div class="line">    }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename = args.length &gt; 0 ? args[0] : <span class="stringliteral">&quot;../data/lena.jpg&quot;</span>;</div><div class="line">        Mat src = Imgcodecs.imread(filename);</div><div class="line">        <span class="keywordflow">if</span> (src.empty()) {</div><div class="line">            System.err.println(<span class="stringliteral">&quot;Cannot read image: &quot;</span> + filename);</div><div class="line">            System.exit(0);</div><div class="line">        }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">parser = argparse.ArgumentParser(description=<span class="stringliteral">&#39;Code for Histogram Calculation tutorial.&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--input&#39;</span>, help=<span class="stringliteral">&#39;Path to input image.&#39;</span>, default=<span class="stringliteral">&#39;lena.jpg&#39;</span>)</div><div class="line">args = parser.parse_args()</div><div class="line"></div><div class="line">src = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">cv.imread</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(args.input))</div><div class="line"><span class="keywordflow">if</span> src <span class="keywordflow">is</span> <span class="keywordtype">None</span>:</div><div class="line">    <a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;Could not open or find the image:&#39;</span>, args.input)</div><div class="line">    exit(0)</div></div><!-- fragment --> </div> <ul>
<li>Separate the source image in its three R,G and B planes. For this we use the OpenCV function <a class="el" href="../../d2/de8/group__core__array.html#ga0547c7fed86152d7e9d0096029c8518a">cv::split</a> :</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    vector&lt;Mat&gt; bgr_planes;</div><div class="line">    <a class="code" href="../../d2/de8/group__core__array.html#ga0547c7fed86152d7e9d0096029c8518a">split</a>( src, bgr_planes );</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        List&lt;Mat&gt; bgrPlanes = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        Core.split(src, bgrPlanes);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">bgr_planes = <a class="code" href="../../d2/de8/group__core__array.html#ga8027f9deee1e42716be8039e5863fbd9">cv.split</a>(src)</div></div><!-- fragment --> </div> <p> our input is the image to be divided (this case with three channels) and the output is a vector of Mat )</p>
<ul>
<li>Now we are ready to start configuring the <b>histograms</b> for each plane. Since we are working with the B, G and R planes, we know that our values will range in the interval \([0,255]\)</li>
<li>Establish the number of bins (5, 10...):</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    <span class="keywordtype">int</span> histSize = 256;</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <span class="keywordtype">int</span> histSize = 256;</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">histSize = 256</div></div><!-- fragment --> </div> <ul>
<li>Set the range of values (as we said, between 0 and 255 )</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    <span class="keywordtype">float</span> range[] = { 0, 256 }; <span class="comment">//the upper boundary is exclusive</span></div><div class="line">    <span class="keyword">const</span> <span class="keywordtype">float</span>* histRange = { range };</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <span class="keywordtype">float</span>[] range = {0, 256}; <span class="comment">//the upper boundary is exclusive</span></div><div class="line">        MatOfFloat histRange = <span class="keyword">new</span> MatOfFloat(range);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">histRange = (0, 256) <span class="comment"># the upper boundary is exclusive</span></div></div><!-- fragment --> </div> <ul>
<li>We want our bins to have the same size (uniform) and to clear the histograms in the beginning, so:</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    <span class="keywordtype">bool</span> uniform = <span class="keyword">true</span>, accumulate = <span class="keyword">false</span>;</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <span class="keywordtype">boolean</span> accumulate = <span class="keyword">false</span>;</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">accumulate = <span class="keyword">False</span></div></div><!-- fragment --> </div> <ul>
<li>We proceed to calculate the histograms by using the OpenCV function <a class="el" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">cv::calcHist</a> :</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    Mat b_hist, g_hist, r_hist;</div><div class="line">    <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">calcHist</a>( &amp;bgr_planes[0], 1, 0, Mat(), b_hist, 1, &amp;histSize, &amp;histRange, uniform, accumulate );</div><div class="line">    <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">calcHist</a>( &amp;bgr_planes[1], 1, 0, Mat(), g_hist, 1, &amp;histSize, &amp;histRange, uniform, accumulate );</div><div class="line">    <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d">calcHist</a>( &amp;bgr_planes[2], 1, 0, Mat(), r_hist, 1, &amp;histSize, &amp;histRange, uniform, accumulate );</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        Mat bHist = <span class="keyword">new</span> Mat(), gHist = <span class="keyword">new</span> Mat(), rHist = <span class="keyword">new</span> Mat();</div><div class="line">        Imgproc.calcHist(bgrPlanes, <span class="keyword">new</span> MatOfInt(0), <span class="keyword">new</span> Mat(), bHist, <span class="keyword">new</span> MatOfInt(histSize), histRange, accumulate);</div><div class="line">        Imgproc.calcHist(bgrPlanes, <span class="keyword">new</span> MatOfInt(1), <span class="keyword">new</span> Mat(), gHist, <span class="keyword">new</span> MatOfInt(histSize), histRange, accumulate);</div><div class="line">        Imgproc.calcHist(bgrPlanes, <span class="keyword">new</span> MatOfInt(2), <span class="keyword">new</span> Mat(), rHist, <span class="keyword">new</span> MatOfInt(histSize), histRange, accumulate);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">b_hist = <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga6ca1876785483836f72a77ced8ea759a">cv.calcHist</a>(bgr_planes, [0], <span class="keywordtype">None</span>, [histSize], histRange, accumulate=accumulate)</div><div class="line">g_hist = <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga6ca1876785483836f72a77ced8ea759a">cv.calcHist</a>(bgr_planes, [1], <span class="keywordtype">None</span>, [histSize], histRange, accumulate=accumulate)</div><div class="line">r_hist = <a class="code" href="../../d6/dc7/group__imgproc__hist.html#ga6ca1876785483836f72a77ced8ea759a">cv.calcHist</a>(bgr_planes, [2], <span class="keywordtype">None</span>, [histSize], histRange, accumulate=accumulate)</div></div><!-- fragment --> </div> <ul>
<li>where the arguments are (<b>C++ code</b>):<ul>
<li><b>&amp;bgr_planes[0]:</b> The source array(s)</li>
<li><b>1</b>: The number of source arrays (in this case we are using 1. We can enter here also a list of arrays )</li>
<li><b>0</b>: The channel (<em>dim</em>) to be measured. In this case it is just the intensity (each array is single-channel) so we just write 0.</li>
<li><b>Mat()</b>: A mask to be used on the source array ( zeros indicating pixels to be ignored ). If not defined it is not used</li>
<li><b>b_hist</b>: The Mat object where the histogram will be stored</li>
<li><b>1</b>: The histogram dimensionality.</li>
<li><b>histSize:</b> The number of bins per each used dimension</li>
<li><b>histRange:</b> The range of values to be measured per each dimension</li>
<li><b>uniform</b> and <b>accumulate</b>: The bin sizes are the same and the histogram is cleared at the beginning.</li>
</ul>
</li>
<li>Create an image to display the histograms:</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    <span class="keywordtype">int</span> hist_w = 512, hist_h = 400;</div><div class="line">    <span class="keywordtype">int</span> bin_w = <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>( (<span class="keywordtype">double</span>) hist_w/histSize );</div><div class="line"></div><div class="line">    Mat histImage( hist_h, hist_w, <a class="code" href="../../d1/d1b/group__core__hal__interface.html#ga88c4cd9de76f678f33928ef1e3f96047">CV_8UC3</a>, <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>( 0,0,0) );</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <span class="keywordtype">int</span> histW = 512, histH = 400;</div><div class="line">        <span class="keywordtype">int</span> binW = (int) Math.round((<span class="keywordtype">double</span>) histW / histSize);</div><div class="line"></div><div class="line">        Mat histImage = <span class="keyword">new</span> Mat( histH, histW, CvType.CV_8UC3, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>( 0,0,0) );</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">hist_w = 512</div><div class="line">hist_h = 400</div><div class="line">bin_w = int(round( hist_w/histSize ))</div><div class="line"></div><div class="line">histImage = np.zeros((hist_h, hist_w, 3), dtype=np.uint8)</div></div><!-- fragment --> </div> <ul>
<li>Notice that before drawing, we first <a class="el" href="../../dc/d84/group__core__basic.html#ga1b6a396a456c8b6c6e4afd8591560d80">cv::normalize</a> the histogram so its values fall in the range indicated by the parameters entered:</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga1b6a396a456c8b6c6e4afd8591560d80">normalize</a>(b_hist, b_hist, 0, histImage.rows, <a class="code" href="../../d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa9f0c1c342a18114d47b516a88e29822e">NORM_MINMAX</a>, -1, Mat() );</div><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga1b6a396a456c8b6c6e4afd8591560d80">normalize</a>(g_hist, g_hist, 0, histImage.rows, <a class="code" href="../../d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa9f0c1c342a18114d47b516a88e29822e">NORM_MINMAX</a>, -1, Mat() );</div><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga1b6a396a456c8b6c6e4afd8591560d80">normalize</a>(r_hist, r_hist, 0, histImage.rows, <a class="code" href="../../d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa9f0c1c342a18114d47b516a88e29822e">NORM_MINMAX</a>, -1, Mat() );</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        Core.normalize(bHist, bHist, 0, histImage.rows(), Core.NORM_MINMAX);</div><div class="line">        Core.normalize(gHist, gHist, 0, histImage.rows(), Core.NORM_MINMAX);</div><div class="line">        Core.normalize(rHist, rHist, 0, histImage.rows(), Core.NORM_MINMAX);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line"><a class="code" href="../../d2/de8/group__core__array.html#ga7bcf47a1df78cf575162e0aed44960cb">cv.normalize</a>(b_hist, b_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)</div><div class="line"><a class="code" href="../../d2/de8/group__core__array.html#ga7bcf47a1df78cf575162e0aed44960cb">cv.normalize</a>(g_hist, g_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)</div><div class="line"><a class="code" href="../../d2/de8/group__core__array.html#ga7bcf47a1df78cf575162e0aed44960cb">cv.normalize</a>(r_hist, r_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)</div></div><!-- fragment --> </div> <ul>
<li>this function receives these arguments (<b>C++ code</b>):<ul>
<li><b>b_hist:</b> Input array</li>
<li><b>b_hist:</b> Output normalized array (can be the same)</li>
<li><b>0</b> and <b>histImage.rows</b>: For this example, they are the lower and upper limits to normalize the values of <b>r_hist</b></li>
<li><b>NORM_MINMAX:</b> Argument that indicates the type of normalization (as described above, it adjusts the values between the two limits set before)</li>
<li><b>-1:</b> Implies that the output normalized array will be the same type as the input</li>
<li><b>Mat():</b> Optional mask</li>
</ul>
</li>
<li>Observe that to access the bin (in this case in this 1D-Histogram):</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    <span class="keywordflow">for</span>( <span class="keywordtype">int</span> i = 1; i &lt; histSize; i++ )</div><div class="line">    {</div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">line</a>( histImage, <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i-1), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(b_hist.at&lt;<span class="keywordtype">float</span>&gt;(i-1)) ),</div><div class="line">              <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(b_hist.at&lt;<span class="keywordtype">float</span>&gt;(i)) ),</div><div class="line">              <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>( 255, 0, 0), 2, 8, 0  );</div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">line</a>( histImage, <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i-1), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(g_hist.at&lt;<span class="keywordtype">float</span>&gt;(i-1)) ),</div><div class="line">              <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(g_hist.at&lt;<span class="keywordtype">float</span>&gt;(i)) ),</div><div class="line">              <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>( 0, 255, 0), 2, 8, 0  );</div><div class="line">        <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">line</a>( histImage, <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i-1), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(r_hist.at&lt;<span class="keywordtype">float</span>&gt;(i-1)) ),</div><div class="line">              <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>( bin_w*(i), hist_h - <a class="code" href="../../db/de0/group__core__utils.html#ga085eca238176984a0b72df2818598d85">cvRound</a>(r_hist.at&lt;<span class="keywordtype">float</span>&gt;(i)) ),</div><div class="line">              <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>( 0, 0, 255), 2, 8, 0  );</div><div class="line">    }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <span class="keywordtype">float</span>[] bHistData = <span class="keyword">new</span> <span class="keywordtype">float</span>[(int) (bHist.total() * bHist.channels())];</div><div class="line">        bHist.get(0, 0, bHistData);</div><div class="line">        <span class="keywordtype">float</span>[] gHistData = <span class="keyword">new</span> <span class="keywordtype">float</span>[(int) (gHist.total() * gHist.channels())];</div><div class="line">        gHist.get(0, 0, gHistData);</div><div class="line">        <span class="keywordtype">float</span>[] rHistData = <span class="keyword">new</span> <span class="keywordtype">float</span>[(int) (rHist.total() * rHist.channels())];</div><div class="line">        rHist.get(0, 0, rHistData);</div><div class="line"></div><div class="line">        <span class="keywordflow">for</span>( <span class="keywordtype">int</span> i = 1; i &lt; histSize; i++ ) {</div><div class="line">            Imgproc.line(histImage, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i - 1), histH - Math.round(bHistData[i - 1])),</div><div class="line">                    <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i), histH - Math.round(bHistData[i])), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(255, 0, 0), 2);</div><div class="line">            Imgproc.line(histImage, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i - 1), histH - Math.round(gHistData[i - 1])),</div><div class="line">                    <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i), histH - Math.round(gHistData[i])), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(0, 255, 0), 2);</div><div class="line">            Imgproc.line(histImage, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i - 1), histH - Math.round(rHistData[i - 1])),</div><div class="line">                    <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(binW * (i), histH - Math.round(rHistData[i])), <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(0, 0, 255), 2);</div><div class="line">        }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line"><span class="keywordflow">for</span> i <span class="keywordflow">in</span> range(1, histSize):</div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">cv.line</a>(histImage, ( bin_w*(i-1), hist_h - int(b_hist[i-1]) ),</div><div class="line">            ( bin_w*(i), hist_h - int(b_hist[i]) ),</div><div class="line">            ( 255, 0, 0), thickness=2)</div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">cv.line</a>(histImage, ( bin_w*(i-1), hist_h - int(g_hist[i-1]) ),</div><div class="line">            ( bin_w*(i), hist_h - int(g_hist[i]) ),</div><div class="line">            ( 0, 255, 0), thickness=2)</div><div class="line">    <a class="code" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2">cv.line</a>(histImage, ( bin_w*(i-1), hist_h - int(r_hist[i-1]) ),</div><div class="line">            ( bin_w*(i), hist_h - int(r_hist[i]) ),</div><div class="line">            ( 0, 0, 255), thickness=2)</div></div><!-- fragment --> </div> <p> we use the expression (<b>C++ code</b>): </p><div class="fragment"><div class="line">b_hist.at&lt;<span class="keywordtype">float</span>&gt;(i)</div></div><!-- fragment --><p> where \(i\) indicates the dimension. If it were a 2D-histogram we would use something like: </p><div class="fragment"><div class="line">b_hist.at&lt;<span class="keywordtype">float</span>&gt;( i, j )</div></div><!-- fragment --><ul>
<li>Finally we display our histograms and wait for the user to exit:</li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;Source image&quot;</span>, src );</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;calcHist Demo&quot;</span>, histImage );</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">waitKey</a>();</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        HighGui.imshow( <span class="stringliteral">&quot;Source image&quot;</span>, src );</div><div class="line">        HighGui.imshow( <span class="stringliteral">&quot;calcHist Demo&quot;</span>, histImage );</div><div class="line">        HighGui.waitKey(0);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line"><a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;Source image&#39;</span>, src)</div><div class="line"><a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;calcHist Demo&#39;</span>, histImage)</div><div class="line"><a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">cv.waitKey</a>()</div></div><!-- fragment --> </div> <h2>Result </h2>
<ol type="1">
<li><p class="startli">Using as input argument an image like the one shown below:</p>
<div class="image">
<img src="../../Histogram_Calculation_Original_Image.jpg" alt="Histogram_Calculation_Original_Image.jpg"/>
</div>
</li>
<li><p class="startli">Produces the following histogram:</p>
<div class="image">
<img src="../../Histogram_Calculation_Result.jpg" alt="Histogram_Calculation_Result.jpg"/>
</div>
 </li>
</ol>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:35 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
